/**
* \file CMySQL.h
* \author Corentin Le Bail
* \date 2009-2012
* \brief Fichier de déclarartion de la class CMySQL
*/
//------------------------------------------------------------------------------
#ifndef __CMYSQL_H__
#define __CMYSQL_H__
//------------------------------------------------------------------------------
#include <QString>
#include <QSqlDatabase>
#include <QSqlQuery>
#include "CChamp.h"
#include "CChampText.h"
//------------------------------------------------------------------------------
/**
 * \class CMySQL CMySQL.h "CMySQL.h"
 * \brief Classe singleton d'accès à la base de données
 */
class CMySQL
{
	public:
		/**
		 * \struct _SChampRecherche
		 * \brief Structure représentant les caractéristiques d'un champ de base de données lors du résultat d'une recherche.
		 */
		typedef struct _SChampRecherche
		{
			QString champNom; /**< Nom du champ */
			QString champDescription; /**< Description du champ */
			bool defaut; /**< Champ de retour par défaut ? */
			/**
			 * \fn _SChampRecherche(QString nom="", QString description="", bool d=false)
			 * \brief Constructeur
			 * \param[in] nom Nom du champ
			 * \param[in] description Description du champ
			 * \param[in] d Champ de retour par défaut ?
			 */
			_SChampRecherche(QString nom="", QString description="", bool d=false)
			{ 
				champNom=nom; 
				champDescription=description; 
				defaut=d; 
			}
		}SChampRecherche; //!< typedef
		
		/**
	 	 * \fn static CScript *getInstance(void)
	 	 * \return L'instance de la classe
		 */
		static CMySQL *getInstance(void);
		/**
		 * \fn bool dbConnect(QString host, QString user, QString passWord, QString base)
		 * \brief Se connecte à la base de données
		 * \param[in] host Adresse du serveur MYSQL
		 * \param[in] user Utilisateur autorisé à se connecter à la base de données
		 * \param[in] passWord Mot de l'autilisateur
		 * \param[in] base Nom de la base de données
		 * \return True si la connection aboutis, false sinon
		 */
		bool dbConnect(QString host, QString user, QString passWord, QString base);
		/**
		 * \fn QString getBase(void)
		 * \return Le nom de la base de données
		 */
		QString getBase(void) { return _base; }
		/**
		 * \fn void setBase(QString base)
		 * \brief Affecte le nom de base de données
		 * \param[in] base Le nom de la base de données
		 */
		void setBase(QString base) { _base=base; }
		/**
		 * \fn QString getUser(void)
		 * \return Le nom de l'utilisateur connecté à la base de données
		 */
		QString getUser(void) { return _user; }
		/**
		 * \fn void setUser(QString user)
		 * \brief Affecte le nom de l'utilisateur connecté à la base de données
		 * \param[in] user Le nom de l'utilisateur connecté à la base de données
		 */
		void setUser(QString user) { _user=user; }
		/**
		 * \fn bool execQuery(QString requete, bool showMessage=true, QVariant *lastInsertId=0)
		 * \brief Exécute une requete SQL
		 * \param[in] requete La reqête
		 * \param[in] showMessage Affiche ou non l'erreur SQL si il y lieu.
		 * \param[out] lastInsertId Dernier id inséré.
		 * \return True en cas de succès, false sinon.
		 */
		bool execQuery(QString requete, bool showMessage=true, QVariant *lastInsertId=0);
		/**
		 * \fn bool execQuery(QString requete, QSqlQuery **query, bool showMessage=true, QVariant *lastInsertId=0)
		 * \brief Exécute une requete SQL, l'objet query est à détruire par le lanceur
		 * \param[in] requete La reqête
		 * \param[out] query Un objet QSqlQuery contenant le résultat de la requête
		 * \param[in] showMessage Affiche ou non l'erreur SQL si il y lieu.
		 * \param[out] lastInsertId Dernier id inséré.
		 * \return True en cas de succès, false sinon.
		 */
		bool execQuery(QString requete, QSqlQuery **query, bool showMessage=true, QVariant *lastInsertId=0);
		/**
		 * \fn bool execQuery(QSqlQuery *query, bool showMessage=true, QVariant *lastInsertId=0)
		 * \brief Exécute une requete SQL, l'objet query est à détruire par le lanceur
		 * \param[in,out] query Un objet QSqlQuery contenant la requete préparé et retourant le résultat de la requête
		 * \param[in] showMessage Affiche ou non l'erreur SQL si il y lieu.
		 * \param[out] lastInsertId Dernier id inséré.
		 * \return True en cas de succès, false sinon.
		 */
		bool execQuery(QSqlQuery *query, bool showMessage=true, QVariant *lastInsertId=0);
		/**
		 * \deprecated  Utiliser les objets CDAO...
		 * \fn int getNbEnregistrement(QString tableName)
		 * \brief Calcul le nombre d'enregistrement d'une table
		 * \param[in] tableName Le nom de la table
		 * \return Le nombre d'enregistrement.
		 */
		int getNbEnregistrement(QString tableName);
		/**
		 * \fn QString getNextCode(QString tableName, QString champName, QString condition="")
		 * \brief Calcul un nouveau numéro en fonction d'une condition pour une table et un champ donnée 
		 * \param[in] tableName Le nom de la table
		 * \param[in] champName Le nom du champ
		 * \param[in] condition La condition du calcul
		 * \return Le nouveau numéro.
		 */
		QString getNextCode(QString tableName, QString champName, QString condition="");
		/**
		 * \fn bool existe(QString tableName, QString champName, QString value)
		 * \param[in] tableName Le nom de la table
		 * \param[in] champName Le nom du champ
		 * \param[in] value Valeur à rechercher
		 * \return True si un enregistrement de la table tableName dont le champ champName a la valeur value 
		 */
		bool existe(QString tableName, QString champName, QString value);
		/**
		 * \fn bool canDelete(QString tableName, QString champName, QString value)
		 * \brief Affiche un message d'erreur si un enregistrement de la table tableName dont le champ champName a la valeur value
		 * \param[in] tableName Le nom de la table
		 * \param[in] champName Le nom du champ
		 * \param[in] value Valeur à rechercher
		 * \return False si un enregistrement de la table tableName dont le champ champName a la valeur value 
		 */
		bool canDelete(QString tableName, QString champName, QString value);
		/**
		 * \fn QVector<SChampRecherche> getChampsRecherche(QString tableName, bool includeTableName=false)
		 * \brief Recherche les champs d'une table ayant l'arrtibut recherche
		 * \param[in] tableName Le nom de la table
		 * \param[in] includeTableName Inclus le nom de la table dans le nom du champ ?
		 * \return Une liste de SChampRecherche
		 */
		QVector<SChampRecherche> getChampsRecherche(QString tableName, bool includeTableName=false); 
		/**
		 * \deprecated  Utiliser les objets CDAO...
		 * \fn QDate getCurrentDate(void)
		 * \return La date courante du serveur
		 */
		QDate getCurrentDate(void);
		/**
		 * \deprecated  Utiliser les objets CDAO...
		 * \fn QTime getCurrentTime(void)
		 * \return L'heure courante du serveur
		 */
		QTime getCurrentTime(void);
		/**
		 * \fn bool versionOk(QString &versionMinLogiciel, QString &versionBase)
		 * \brief Vérifi la cohérence des versions
		 * \param[out] versionMinLogiciel La version minimale du logiciel
		 * \param[out] versionBase La version de la base
		 * \return True si les version sont cohérentes, false sinon
		 */
		bool versionOk(QString &versionMinLogiciel, QString &versionBase);
		/**
		 * \fn void close(void)
		 * \brief Ferme la connection à la base de données
		 */
		void close(void);
		/**
		* \fn QSqlDatabase getDatabase(void) const
		* \brief Retourne l'objet base de données
		*/
		QSqlDatabase getDatabase(void) const { return db; }
		/**
		 * \fn bool isConnect(void)
		 * \return true si la connection avec la base de données est active, false sinon
		 */
		bool isConnect(void) { return db.isOpen(); }
		/**
		 * \fn QSqlQuery * getQuery(void)
		 * \return Un object QSqlQuery
		 */
		QSqlQuery * getQuery(void) { _query->clear(); return _query; }
		/**
		 * \fn QString makeDocName(QString code, QString prefix, QString champDate, QString tableName)
		 * \param[in] code Le code du document
		 * \param[in] prefix Le prefix du document
		 * \param[in] champDate Le champ contenant la date du document
		 * \param[in] tableName la table de référence;
		 * \return Le nom du document
		 */
		QString makeDocName(QString champCode, QString prefix, QString champDate, QString tableName);
	private:
		static CMySQL *_instance;
		QSqlDatabase db;
		QSqlQuery *_query;
		QString _base;
		QString _user;
		
		CMySQL(void) { _base=""; }
};
//------------------------------------------------------------------------------
#endif //__CMYSQL_H__
//------------------------------------------------------------------------------